package com.csii.security.authentication.mobile;

import com.csii.security.authentication.GeneralAuthenticationFailureHandler;
import com.csii.security.authentication.exception.ValidateCodeException;
import com.csii.security.properites.SecurityConstants;
import com.csii.security.utils.RequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 校验用户输入的手机验证码是否正确
 * @Auther: ian
 */
@Component // 不要少了
public class MobileValidateFilter extends OncePerRequestFilter {


    @Autowired
    GeneralAuthenticationFailureHandler generalAuthenticationFailureHandler;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        // 1. 判断 请求是否为手机登录，且post请求
        if(request.getRequestURI().endsWith("/mobile/form")
            && "post".equalsIgnoreCase(request.getMethod())) {
            try {
                // 校验验证码合法性
                validate(request);
            }catch (AuthenticationException e) {
                // 交给失败处理器进行处理异常
                generalAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);
                // 一定要记得结束
                return;
            }
        }

        // 放行
        filterChain.doFilter(request, response);
    }

    private void validate(HttpServletRequest request) {
        RequestUtils.getParamsToRequestAttribute(request);
        String key = SecurityConstants.MOBILE_REDIS_KEY+(String) request.getAttribute("mobile");
        // 先获取redis中的验证码
        String code =
                (String)redisTemplate.opsForValue().get(key);
        // 获取用户输入的验证码
        String inpuCode = (String) request.getAttribute("mobileCode");

        // 判断是否正确
        if(StringUtils.isEmpty(inpuCode)) {
            throw new ValidateCodeException("验证码不能为空");
        }

        if(!inpuCode.equalsIgnoreCase(code)) {
            throw new ValidateCodeException("验证码输入错误");
        }
        //清除缓存
        redisTemplate.delete(key);
    }
}
